import FileSaver from "file-saver";
// 不使用import * 的方式导入xlsx会报错
import * as XLSX from "xlsx";

/**
 * @demoJx(2021/4/19) json转excel文件
 * @param {Object} jsonData 传入的json数据
 * @param {String} options.fileName 导出的文件名称
 * @param {Function} options.parseDataFun([传入的json数据]) json数据前处理方法,返回{headerList,headers,rows}数据
 * @param {Function} options.callback 回调方法
 */
// var JSONToExcelConvertor = function (jsonData, options = {}) {
//   this.jsonData = jsonData || {
//     headerList: [],
//     headers: [],
//     rows: [],
//   };
//   this.fileName = options.fileName || "sheet";
//   this.parseDataFun = options.parseDataFun;
//   this.callback = options.callback;
//   this.init();
// };
// JSONToExcelConvertor.prototype = {
//   constructor: JSONToExcelConvertor,
//   init() {
//     var exportJson = this._parseData(this.jsonData);
//     var excel = this._createExcel(exportJson);
//     this._exportExcel(excel, this.fileName);
//   },
//   _parseData(jsonData) {
//     this.parseDataFun && (jsonData = this.parseDataFun(jsonData));
//     var headerKeys = [];
//     var headers = [];
//     var rows = [];
//     // 组装表头数据
//     jsonData.headers &&
//       jsonData.headers.forEach(function (item) {
//         if (Object.prototype.toString.call(item) === "[object Object]") {
//           headers.push(item.name);
//           headerKeys.push(item.id);
//         } else {
//           headers.push(item);
//         }
//       });
//     // 组装行数据
//     jsonData.rows &&
//       jsonData.rows.forEach(function (item, index) {
//         if (Object.prototype.toString.call(item) === "[object Object]") {
//           !rows[index] && (rows[index] = []);
//           headerKeys.forEach(function (key) {
//             rows[index].push(item[key]);
//           });
//         } else {
//           rows.push(item);
//         }
//       });
//     return {
//       headerList: jsonData.headerList || [],
//       headers,
//       rows,
//     };
//   },
//   _createExcel(jsonData) {
//     var excel = "<table>";
//     var row = "";

//     // 设置多表头
//     if (jsonData.headerList.length) {
//       jsonData.headerList.forEach(function (header) {
//         row = "<tr>";
//         header.forEach(function (item) {
//           row +=
//             "<td colspan='" +
//             item.colspan +
//             "' rowspan='" +
//             item.rowspan +
//             "'>" +
//             item.name +
//             "</td>";
//         });
//         excel += row + "</tr>";
//       });
//     }

//     // 设置表头
//     if (jsonData.headers.length) {
//       row = "<tr>";
//       jsonData.headers.forEach(function (item) {
//         row += "<td>" + item + "</td>";
//       });
//       //换行
//       excel += row + "</tr>";
//     }

//     //设置数据
//     if (jsonData.rows.length) {
//       jsonData.rows.forEach(function (rowList) {
//         row = "<tr>";
//         rowList.forEach(function (item) {
//           if (Object.prototype.toString.call(item) === "[object Object]") {
//             row +=
//               "<td colspan='" +
//               item.colspan +
//               "' rowspan='" +
//               item.rowspan +
//               "'>" +
//               item.name +
//               "</td>";
//           } else {
//             row += "<td>" + item + "</td>";
//           }
//         });
//         //换行
//         excel += row + "</tr>";
//       });
//     }

//     excel += "</table>";
//     return excel;
//   },
//   _exportExcel(excel, fileName) {
//     var excelFile =
//       "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>";
//     excelFile +=
//       '<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">';
//     excelFile +=
//       '<meta http-equiv="content-type" content="application/vnd.ms-excel';
//     excelFile += '; charset=UTF-8">';
//     excelFile += "<head>";
//     excelFile += "<!--[if gte mso 9]>";
//     excelFile += "<xml>";
//     excelFile += "<x:ExcelWorkbook>";
//     excelFile += "<x:ExcelWorksheets>";
//     excelFile += "<x:ExcelWorksheet>";
//     excelFile += "<x:Name>";
//     excelFile += "sheet";
//     excelFile += "</x:Name>";
//     excelFile += "<x:WorksheetOptions>";
//     excelFile += "<x:DisplayGridlines/>";
//     excelFile += "</x:WorksheetOptions>";
//     excelFile += "</x:ExcelWorksheet>";
//     excelFile += "</x:ExcelWorksheets>";
//     excelFile += "</x:ExcelWorkbook>";
//     excelFile += "</xml>";
//     excelFile += "<![endif]-->";
//     excelFile += "</head>";
//     excelFile += "<body>";
//     excelFile += excel;
//     excelFile += "</body>";
//     excelFile += "</html>";

//     var uri =
//       "data:application/vnd.ms-excel;charset=utf-8," +
//       encodeURIComponent(excelFile);

//     var link = document.createElement("a");
//     link.href = uri;

//     link.style = "visibility:hidden";
//     link.download = fileName + ".xlsx";

//     document.body.appendChild(link);
//     link.click();
//     document.body.removeChild(link);
//     this.callback && this.callback();
//   },
// };

//   // 另一个将json下载为excel的函数
//   export function json2Xlsx() {
//     const btn = document.querySelector("#btn");

//     btn.addEventListener("click", (ev) => {
//       // 假设这个是数据源 一般是直接拉服务器上的数据, 进行下载
//       const data = [
//         { id: 1, name: "张三", age: 10 },
//         { id: 2, name: "张珊", age: 10 },
//         { id: 3, name: "李四", age: 10 },
//       ];

//       // 展示名称
//       const headerReplace = { id: "ID", name: "名称", age: "年龄" };

//       // 数据源
//       const sheet = [headerReplace, ...data];

//       // 创建一个sheet表格   使用json_to_sheet, 数据格式比较为  数组包对象, 不然会报错
//       const worksheet = XLSX.utils.json_to_sheet(sheet, {
//         // 这里可以通过设置header, 来对导出数据 列 顺序的排序
//         // 实测可以只写一部分, 也可以整体排序
//         // ["id", "name", "age"] 相当于把上面整个表头给限制顺序了
//         header: ["age"],
//         // 跳过 Header, 就是把原来表格数据的表头去掉了, headerReplace渲染的数据 "冒充" 表头了
//         skipHeader: true,
//       });

//       // 简单理解为在内存中 创建一个xlsx 文件
//       const newWorkBook = XLSX.utils.book_new();
//       // 把worksheet添加到workbook中
//       XLSX.utils.book_append_sheet(newWorkBook, worksheet, "SheetJS");
//       // 写入文件, CHROME浏览器会直接下载, 后面的是文件名称和后缀
//       XLSX.writeFile(newWorkBook, "订单.xlsx");
//     });
//   }

// Json数组转换为Xlsx，提取自上一个方法的核心逻辑
export function json2Xlsx(data, tableName) {
  // 假设这个是数据源 一般是直接拉服务器上的数据, 进行下载
  // const data = [
  //     { id: 1, name: "张三", age: 10 },
  //     { id: 2, name: "张珊", age: 10 },
  //     { id: 3, name: "李四", age: 10 },
  //   ];

  // 展示名称
  //   const headerReplace = { id: "ID", name: "名称", age: "年龄" };

  // 数据源，可以不带表头替换
  //   const sheet = [headerReplace, ...data];
  const sheet = [...data];

  // 创建一个sheet表格   使用json_to_sheet, 数据格式比较为  数组包对象, 不然会报错
  const worksheet = XLSX.utils.json_to_sheet(sheet, {
    // 这里可以通过设置header, 来对导出数据 列 顺序的排序
    // 实测可以只写一部分, 也可以整体排序
    // ["id", "name", "age"] 相当于把上面整个表头给限制顺序了
    // header: ["age"],
    // 跳过 Header, 就是把原来表格数据的表头去掉了, headerReplace渲染的数据 "冒充" 表头了
    // skipHeader: true,
  });

  // 简单理解为在内存中 创建一个xlsx 文件
  const newWorkBook = XLSX.utils.book_new();
  // 把worksheet添加到workbook中
  XLSX.utils.book_append_sheet(newWorkBook, worksheet, "SheetJS");
  // 写入文件, CHROME浏览器会直接下载, 后面的是文件名称和后缀
  XLSX.writeFile(newWorkBook, tableName + ".xlsx");
}

/**
 * 一个确定有效的导出表格为Excel的方法
 * 导出对象为页面上的表格元素
 * @param {String} index 标签编号
 * @returns 
 */
export function table2Excel(index,...id) {
  var wb = XLSX.utils.table_to_book(
    // querySelector对应选择器的元素标签
    document.querySelector(".result-table-" + index)
  );
  
  
  let range=wb.Sheets.Sheet1['!ref']
  let index1=range.indexOf('J')
  let end=range.substring(index1+1,range.length)
  console.log('测试大小',end)
  if(index==-2){
    wb.Sheets.Sheet1['!ref']=`A1:F${end}`
  }
  var wbout = XLSX.write(wb, {
    bookType: "xlsx",
    bookSST: true,
    type: "array",
  });
  console.log("wbout:");
  console.log(wbout);
  try {
    let timeStamp = new Date().valueOf();
    let fileName = "结果_" + timeStamp + ".xlsx";
    if(index==-1||index==-2){
      fileName=id+".xlsx"
    }
    
    FileSaver.saveAs(
      new Blob([wbout], { type: "application/octet-stream" }),
      fileName
    );
  } catch (e) {
    if (typeof console !== "undefined") console.log(e, wbout);
  }
  return wbout;
}


// 这个对象包含了Json转为CSV的流程
export var JSonToCSV = {
  /*
   * obj是一个对象，其中包含有：
   * ## data 是导出的具体数据
   * ## fileName 是导出时保存的文件名称 是string格式
   * ## showLabel 表示是否显示表头 默认显示 是布尔格式
   * ## columns 是表头对象，且title和key必须一一对应，包含有
        title:[], // 表头展示的文字
        key:[], // 获取数据的Key
        formatter: function() // 自定义设置当前数据的 传入(key, value)
   */
    // 调用示例
    // JSonToCSV.setDataConver({
    //   data: [
    //     { name: "张三", amont: "323433.56", proportion: 33.4 },
    //     { name: "李四", amont: "545234.43", proportion: 55.45 },
    //   ],
    //   fileName: "test",
    //   columns: {
    //     title: ["姓名", "金额", "占比"],
    //     key: ["name", "amont", "proportion"],
    //     formatter: function (n, v) {
    //       if (n === "amont" && !isNaN(Number(v))) {
    //         v = v + "";
    //         v = v.split(".");
    //         v[0] = v[0].replace(/(\d)(?=(?:\d{3})+$)/g, "$1,"); // 千分位的设置
    //         return v.join(".");
    //       }
    //       if (n === "proportion") return v + "%";
    //     },
    //   },
    // });
  setDataConver: function(obj) {
    var data = obj['data'],
        ShowLabel = typeof obj['showLabel'] === 'undefined' ? true : obj['showLabel'],
        fileName = (obj['fileName'] || 'UserExport') + '.csv',
        columns = obj['columns'] || {
            title: [],
            key: [],
            formatter: undefined
        };
    // var ShowLabel = typeof ShowLabel === 'undefined' ? true : ShowLabel;
    ShowLabel = typeof ShowLabel === 'undefined' ? true : ShowLabel;
    var row = "", CSV = '', key;
    // 如果要现实表头文字
    if (ShowLabel) {
        // 如果有传入自定义的表头文字
        if (columns.title.length) {
            columns.title.map(function(n) {
                row += n + ',';
            });
        } else {
            // 如果没有，就直接取数据第一条的对象的属性
            for (key in data[0]) row += key + ',';
        }
        row = row.slice(0, -1); // 删除最后一个,号，即a,b, => a,b
        CSV += row + '\r\n'; // 添加换行符号
    }
    // 具体的数据处理
    data.map(function(n) {
        row = '';
        // 如果存在自定义key值
        if (columns.key.length) {
            columns.key.map(function(m) {
                row += '"' + (typeof columns.formatter === 'function' ? columns.formatter(m, n[m]) || n[m] : n[m]) + '",';
            });
        } else {
            for (key in n) {
                row += '"' + (typeof columns.formatter === 'function' ? columns.formatter(key, n[key]) || n[key] : n[key]) + '",';
            }
        }
        row.slice(0, row.length - 1); // 删除最后一个,
        CSV += row + '\r\n'; // 添加换行符号
    });
    if(!CSV) return;
    this.SaveAs(fileName, CSV);
  },
  SaveAs: function(fileName, csvData) {
    var bw = this.browser();
    if(!bw['edge'] ||  !bw['ie']) {
      var alink = document.createElement("a");
      alink.id = "linkDwnldLink";
      alink.href = this.getDownloadUrl(csvData);
      document.body.appendChild(alink);
      var linkDom = document.getElementById('linkDwnldLink');
      linkDom.setAttribute('download', fileName);
      linkDom.click();
      document.body.removeChild(linkDom);
    }
  },
  // getDownloadUrl: function(csvData) {
  //   var _utf = "\uFEFF"; // 为了使Excel以utf-8的编码模式，同时也是解决中文乱码的问题
  //   return 'data:attachment/csv;charset=utf-8,' + _utf + encodeURIComponent(csvData);
  // },
  getDownloadUrl: function(csvData) {
    var _utf = "\uFEFF"; // 为了使Excel以utf-8的编码模式，同时也是解决中文乱码的问题
    if (window.Blob && window.URL && window.URL.createObjectURL) {
        // var csvData = new Blob([_utf + csvData], {
        csvData = new Blob([_utf + csvData], {
            type: 'text/csv'
        });
        return URL.createObjectURL(csvData);
    }
    // return 'data:attachment/csv;charset=utf-8,' + _utf + encodeURIComponent(csvData);
  },
  browser: function() {
    var Sys = {};
    var ua = navigator.userAgent.toLowerCase();
    var s;
    // eslint-disable-next-line no-cond-assign
    (s = ua.indexOf('edge') !== - 1 ? Sys.edge = 'edge' : ua.match(/rv:([\d.]+)\) like gecko/)) ? Sys.ie = s[1]:
        // eslint-disable-next-line no-cond-assign
        (s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
        // eslint-disable-next-line no-cond-assign
        (s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
        // eslint-disable-next-line no-cond-assign
        (s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
        // eslint-disable-next-line no-cond-assign
        (s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
        // eslint-disable-next-line no-cond-assign
        (s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;
    return Sys;
  }
};
